#pragma once
#include <iostream>
#include <vector>
#include <queue>
#include <mutex>
#include <functional>

#include "task.hpp"
#include "Thread.hpp"
#include "lockguard.hpp"
const static int N = 5;

// typedef void(*func_t)(int,int);
template <class T>

class ThreadPool
{
public:
    ThreadPool(int num = N) : num_(num)
    {
        pthread_mutex_init(&mtx_, nullptr);
        pthread_cond_init(&cond_, nullptr);
    }
    void init()
    {
        for (int i = 0; i < num_; i++)
        {
            threads_.push_back(Thread(i, threadRoutine, this));
        }
    }
    void start()
    {
        for (int i = 0; i < num_; i++)
        {
            threads_[i].run();
        }
    }
    static void threadRoutine(void *args)
    {
        pthread_detach(pthread_self());
        ThreadPool<T> *tp = static_cast<ThreadPool<T> *>(args);
        while (true)
        {
             T t;
            {//对任务的处理不希望在临界区 所以要加{}
                LockGuard lockguard(tp->Getmutex());

                while (tp->IsEmpty())
                {
                    // 等待
                    tp->ThreadWait();
                }
            }
            t = tp->PopTask();
            t(); // 处理任务不需要在临界区中处理
            // tp->callback_(t.GetResult(),t.GetExitCode());
            std::cout << t.formatArg() << t.formatRes() << std::endl;
        }
    }
    pthread_mutex_t *Getmutex()
    {
        return &mtx_;
    }
    T PopTask() // 走到这一定是只有一个线程 不需要加锁
    {
        T t = tasks_.front();
        tasks_.pop();
        return t;
    }
    // func_t callback(int result,int code)
    // {
    //     callback_(t.GetResult,t.GetExitCode);
    // }
    bool IsEmpty()
    {
        return tasks_.empty();
    }
    void ThreadWait()
    {
        pthread_cond_wait(&cond_, &mtx_);
    }
    void ThreadWakeUp()
    {
        pthread_cond_signal(&cond_);
    }
    void PushTask(const T &task)
    {
        LockGuard lockguard(&mtx_);
        tasks_.push(task);
        ThreadWakeUp();
    }

    ~ThreadPool()
    {
        for (auto &t : threads_)
        {
            t.join();
        }
        pthread_mutex_destroy(&mtx_);
        pthread_cond_destroy(&cond_);
    }

private:
    int num_;
    std::vector<Thread> threads_;
    std::queue<T> tasks_; // 使用stl自动扩容的特性,充当临界资源的角色
    pthread_mutex_t mtx_;
    pthread_cond_t cond_;
    // func_t callback_;
};